From b0a8b7da631af595326d6410c0f243a5623a5cfe Mon Sep 17 00:00:00 2001 From: =?utf8?q?Timm=20B=C3=A4der?= Date: Sun, 6 Jan 2019 06:55:31 +0100 Subject: [PATCH] gl renderer: Only compile the vertex shader once All our programs use the same vertex shader, so don't compile it over and over again. This improves startup times by at least 0.001%, I swear. --- gsk/gl/gskglrenderer.c | 31 ++++++++++++++----------- gsk/gl/gskshaderbuilder.c | 40 +++++++++++++++++++++++--------- gsk/gl/gskshaderbuilderprivate.h | 5 +++- 3 files changed, 50 insertions(+), 26 deletions(-) diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c index 11cca74318..945c4dfc5a 100644 --- a/gsk/gl/gskglrenderer.c +++ b/gsk/gl/gskglrenderer.c @@ -1994,20 +1994,19 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self, int i; static const struct { const char *name; - const char *vs; const char *fs; } program_definitions[] = { - { "blit", "blit.vs.glsl", "blit.fs.glsl" }, - { "color", "blit.vs.glsl", "color.fs.glsl" }, - { "coloring", "blit.vs.glsl", "coloring.fs.glsl" }, - { "color matrix", "blit.vs.glsl", "color_matrix.fs.glsl" }, - { "linear gradient", "blit.vs.glsl", "linear_gradient.fs.glsl" }, - { "blur", "blit.vs.glsl", "blur.fs.glsl" }, - { "inset shadow", "blit.vs.glsl", "inset_shadow.fs.glsl" }, - { "outset shadow", "blit.vs.glsl", "outset_shadow.fs.glsl" }, - { "unblurred outset shadow", "blit.vs.glsl", "unblurred_outset_shadow.fs.glsl" }, - { "border", "blit.vs.glsl", "border.fs.glsl" }, - { "cross fade", "blit.vs.glsl", "cross_fade.fs.glsl" }, + { "blit", "blit.fs.glsl" }, + { "color", "color.fs.glsl" }, + { "coloring", "coloring.fs.glsl" }, + { "color matrix", "color_matrix.fs.glsl" }, + { "linear gradient", "linear_gradient.fs.glsl" }, + { "blur", "blur.fs.glsl" }, + { "inset shadow", "inset_shadow.fs.glsl" }, + { "outset shadow", "outset_shadow.fs.glsl" }, + { "unblurred outset shadow", "unblurred_outset_shadow.fs.glsl" }, + { "border", "border.fs.glsl" }, + { "cross fade", "cross_fade.fs.glsl" }, }; builder = gsk_shader_builder_new (); @@ -2048,13 +2047,17 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self, gsk_shader_builder_add_define (builder, "GSK_DEBUG", "1"); #endif + gsk_shader_builder_set_common_vertex_shader (builder, "blit.vs.glsl", + &shader_error); + + g_assert_no_error (shader_error); + for (i = 0; i < GL_N_PROGRAMS; i ++) { Program *prog = &self->programs[i]; prog->index = i; prog->id = gsk_shader_builder_create_program (builder, - program_definitions[i].vs, program_definitions[i].fs, &shader_error); @@ -2063,7 +2066,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self, g_propagate_prefixed_error (error, shader_error, "Unable to create '%s' program (from %s and %s):\n", program_definitions[i].name, - program_definitions[i].vs, + "blit.vs.glsl", program_definitions[i].fs); g_object_unref (builder); diff --git a/gsk/gl/gskshaderbuilder.c b/gsk/gl/gskshaderbuilder.c index a352a0efec..dc00371889 100644 --- a/gsk/gl/gskshaderbuilder.c +++ b/gsk/gl/gskshaderbuilder.c @@ -15,6 +15,9 @@ struct _GskShaderBuilder char *vertex_preamble; char *fragment_preamble; + + int common_vertex_shader_id; + int version; GPtrArray *defines; @@ -37,6 +40,9 @@ gsk_shader_builder_finalize (GObject *gobject) g_clear_pointer (&self->defines, g_ptr_array_unref); + if (self->common_vertex_shader_id > 0) + glDeleteShader (self->common_vertex_shader_id); + G_OBJECT_CLASS (gsk_shader_builder_parent_class)->finalize (gobject); } @@ -230,27 +236,39 @@ gsk_shader_builder_compile_shader (GskShaderBuilder *builder, return shader_id; } +void +gsk_shader_builder_set_common_vertex_shader (GskShaderBuilder *self, + const char *vertex_shader, + GError **error) +{ + int shader_id; + + + shader_id = gsk_shader_builder_compile_shader (self, + GL_VERTEX_SHADER, + self->vertex_preamble, + vertex_shader, + error); + + g_assert (shader_id > 0); + self->common_vertex_shader_id = shader_id; +} + int gsk_shader_builder_create_program (GskShaderBuilder *builder, - const char *vertex_shader, const char *fragment_shader, GError **error) { - int vertex_id, fragment_id; + int vertex_id; + int fragment_id; int program_id; int status; g_return_val_if_fail (GSK_IS_SHADER_BUILDER (builder), -1); - g_return_val_if_fail (vertex_shader != NULL, -1); g_return_val_if_fail (fragment_shader != NULL, -1); + g_return_val_if_fail (builder->common_vertex_shader_id != 0, -1); - vertex_id = gsk_shader_builder_compile_shader (builder, GL_VERTEX_SHADER, - builder->vertex_preamble, - vertex_shader, - error); - if (vertex_id < 0) - return -1; - + vertex_id = builder->common_vertex_shader_id; fragment_id = gsk_shader_builder_compile_shader (builder, GL_FRAGMENT_SHADER, builder->fragment_preamble, fragment_shader, @@ -290,8 +308,8 @@ gsk_shader_builder_create_program (GskShaderBuilder *builder, out: if (vertex_id > 0) { + /* We delete the common vertex shader when destroying the shader builder */ glDetachShader (program_id, vertex_id); - glDeleteShader (vertex_id); } if (fragment_id > 0) diff --git a/gsk/gl/gskshaderbuilderprivate.h b/gsk/gl/gskshaderbuilderprivate.h index 73f44736fa..025d7a2028 100644 --- a/gsk/gl/gskshaderbuilderprivate.h +++ b/gsk/gl/gskshaderbuilderprivate.h @@ -25,8 +25,11 @@ void gsk_shader_builder_add_define (GskShad const char *define_name, const char *define_value); +void gsk_shader_builder_set_common_vertex_shader (GskShaderBuilder *self, + const char *vertex_shader, + GError **error); + int gsk_shader_builder_create_program (GskShaderBuilder *builder, - const char *vertex_shader, const char *fragment_shader, GError **error); -- 2.30.2